#include "head.h"

int sendFile(int netFd,char *file){
    train_t train;
    // 发送文件名
    train.length = strlen(file);
    memcpy(train.data, file, train.length);
    send(netFd, &train.length, sizeof(train.length), MSG_NOSIGNAL);
    send(netFd, train.data, train.length, MSG_NOSIGNAL);

    // 打开文件并获取大小
    int fd = open(file, O_RDONLY);
    ERROR_CHECK(fd, -1, "open");
    struct stat statbuf;
    fstat(fd, &statbuf);
    off_t filesize = statbuf.st_size;

    // 发送文件总大小
    train .length = sizeof(filesize);
    memcpy(train.data, &filesize, train.length);
    send(netFd, &train.length, sizeof(train.length), MSG_NOSIGNAL);
    send(netFd, train.data, train.length, MSG_NOSIGNAL);

    // 接收已存在的大小
    off_t existing_size = 0;
    recvn(netFd, &train.length, sizeof(train.length));
    recvn(netFd, train.data, train.length);
    memcpy(&existing_size, train.data, train.length);
    printf("Receiver has: %ld bytes\n", existing_size);

    // 定位到续传位置
    off_t remaining = filesize - existing_size;

    //检查传输是否完成
    if(remaining <=0){
        printf("接收方已存在该文件。跳过发送\n");
        close(fd);

        train.length = 0;
        send(netFd,&train.length,sizeof(train.length),MSG_NOSIGNAL);
        return 0;
    }
    printf("sending %ld bytes\n",remaining);

    //大文件使用mmap
    if(filesize >MMAP_THRESHOLD){
        printf("检测到大文件（>100MB），使用mmap优化\n");

        char *map =(char *)mmap(NULL,remaining,PROT_READ,MAP_PRIVATE,fd,existing_size);
        if(map ==MAP_FAILED){
            perror("mmap failed");
            //mmap失败，使用普通传输
            lseek(fd,existing_size,SEEK_SET);

            while(remaining >0){
                bzero(train.data,sizeof(train.data));
                ssize_t read_size = sizeof(train.data);//获取本次要读取的大小
                ssize_t ret = read(fd, train.data,read_size);
                if(ret <= 0) break;
                train.length = ret;
                send(netFd,&train.length,sizeof(train.length),MSG_NOSIGNAL);
                send(netFd,train.data,train.length,MSG_NOSIGNAL);
                remaining -=ret;
            }
        }else{
            printf("mmap Success\n");
            off_t sent = 0;
            while(sent < remaining){
                //如果剩余数据大于缓冲区大小，发送整个缓冲区
                //否则发送剩余的所有数据
                size_t block_size = (remaining - sent)>sizeof(train.data)?sizeof(train.data):remaining -sent;
                train.length = block_size;
                send(netFd,&train.length,sizeof(train.length),MSG_NOSIGNAL);
                send(netFd,map+sent,block_size,MSG_NOSIGNAL);
                sent +=block_size;
            }
            munmap(map,remaining);
        }
    }
    else{
        //小文件普通传输
        printf("小文件，使用正常传输\n");
        lseek(fd,existing_size,SEEK_END);
        while(remaining >0){
            bzero(train.data,sizeof(train.data));
            ssize_t read_size = sizeof(train.data);
            ssize_t ret = read(fd,train.data,read_size);
            if(ret <=0) break;
            train.length = ret;
            send(netFd,&train.length,sizeof(train.length),MSG_NOSIGNAL);
            send(netFd,train.data,train.length,MSG_NOSIGNAL);
            remaining -= ret;
        }
    }
    // 发送结束标记
    train.length = 0;
    send(netFd, &train.length, sizeof(train.length), MSG_NOSIGNAL);
    printf("传输完成\n");
    close(fd);
    return 0;
}



int main(int argc, char *argv[]){

    return 0;
}

